﻿using HalconDotNet;
using Halcon二次开发.Model.工具区域的扩展类;
using Halcon二次开发.Model.自定义控件;
using Halcon二次开发.Tools;
using Halcon二次开发.View.卡尺;
using Halcon二次开发.View.缺陷检测;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Shapes;
using static System.Windows.Forms.LinkLabel;

namespace Halcon二次开发.Controller.缺陷检测
{
    /// <summary>
    /// 斑点分析动作
    /// </summary>
    public class BoldController
    {
        /// <summary>
        /// 当前控件对象
        /// </summary>
        public HwindowFlowNodeUrseControl hwindowFlowNode;

        HSmartWindowControl hw;
        BoldForm form;
        /// <summary>
        /// 该工具的线段对象
        /// </summary>
        List<HDrawingObjectEx> lines = new List<HDrawingObjectEx>();
        /// <summary>
        /// 线段对象
        /// </summary>
        HDrawingObjectEx line;
        /// <summary>
        /// 感兴趣区域集合
        /// </summary>
        List<HObject> hObjects = new List<HObject>();   
        public HObject HideIntputImage;
        /// <summary>
        /// 输入的行-列-角度 坐标
        /// </summary>
        public double[] HideIntputArrayRows, HideIntputArrayColumns, HideIntputArrayPhis;
        /// <summary>
        /// 基准数据的保存路径
        /// </summary>
        string path;
        bool putCheck = false;  //是否放置卡尺
        public BoldController(string path,HwindowFlowNodeUrseControl hwindowFlowNode,BoldForm boldForm)
        {
            //获取当前工位
            this.hwindowFlowNode = hwindowFlowNode;
            this.hw = hwindowFlowNode.hSmartWindowControl1;
            this.form = boldForm;
            this.path = path;
        }


        /// <summary>
        /// 画矩形
        /// </summary>
        /// <param name="hv_WindowHandle">句柄</param>
        /// <param name="ho_ROI_0">画的区域</param>
        public void DrawRecangle()
        {
            if (HideIntputImage == null||HideIntputArrayRows == null)
            {
                throw new Exception("当前图像为空! \r\n");
            }
            ClearObject();
            //这里要标注区域
            if (HideIntputArrayRows != null && HideIntputArrayRows.Length > 0)
            {
                HOperatorSet.SetColor(hw.HalconWindow, "red");
                HOperatorSet.SetDraw(hw.HalconWindow, "fill");
                HOperatorSet.GenCircle(out HObject ho_Biaozhu, HideIntputArrayRows[0], HideIntputArrayColumns[0], 20);
                HOperatorSet.DispObj(ho_Biaozhu, hw.HalconWindow);
                HOperatorSet.SetColor(hw.HalconWindow, "red");
                HOperatorSet.SetDraw(hw.HalconWindow, "margin");
            }

            //定义绘制线的开始坐标与结束坐标
            var lineTuple = new HTuple[] { 50, 100, 0, 100, 100 };
            //创建线的对象
            HDrawingObject lineObj = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.RECTANGLE2, lineTuple);

            lineObj.SetDrawingObjectParams("color","green");

            //线段拖动触发事件注册
            lineObj.OnDrag(LineOnDrag);
            //线段长度修改触发事件注册
            lineObj.OnResize(LineOnResize);

            //永久保留该对象,不然会被垃圾回收机制回收
            line = new HDrawingObjectEx
            {
                HDrawingObject = lineObj,
                hTuples = lineTuple
            };

            form.RowDown.Value = decimal.Parse(line.hTuples[0].D + "");
            form.ColumnDown.Value = decimal.Parse(line.hTuples[1].D + "");
            form.PhiDown.Value = decimal.Parse(line.hTuples[2].D + "");
            form.Length1Down.Value = decimal.Parse(line.hTuples[3].D + "");
            form.Length2Down.Value = decimal.Parse(line.hTuples[4].D + "");

            hw.HalconWindow.AttachDrawingObjectToWindow(lineObj);
        }
        /// <summary>
        /// 线段拖动触发事件
        /// </summary>
        /// <param name="drawid"></param>
        /// <param name="window"></param>
        /// <param name="type"></param>
        public void LineOnDrag(HDrawingObject drawid, HWindow window, string type)
        {
            UpdataDrawingObjecData(drawid);
        }
        /// <summary>
        /// 线段长度修改触发事件
        /// </summary>
        /// <param name="drawid"></param>
        /// <param name="window"></param>
        /// <param name="type"></param>
        public void LineOnResize(HDrawingObject drawid, HWindow window, string type)
        {
            UpdataDrawingObjecData(drawid);
        }
        /// <summary>
        /// 线段拖动修改长度方法
        /// </summary>
        /// <param name="drawid"></param>
        public void UpdataDrawingObjecData(HDrawingObject drawid)
        {
            //创建一个要得到对象属性的元组
            var attTuple = new HTuple("row", "column", "phi", "length1", "length2");
            //获取对应的属性
            var valueTuple = drawid.GetDrawingObjectParams(attTuple);
            //对对应的属性进行封装一下,后面好加入到集合中
            var attValues = new HTuple[] { valueTuple[0], valueTuple[1], valueTuple[2], valueTuple[3], valueTuple[4] };
            //更新数据
            line.hTuples = attValues;

            form.RowDown.Value = decimal.Parse(line.hTuples[0].D+"");
            form.ColumnDown.Value = decimal.Parse(line.hTuples[1].D + "");
            try
            {
                form.PhiDown.Value = decimal.Parse(line.hTuples[2].D + "");
            }
            catch { }
            form.Length1Down.Value = decimal.Parse(line.hTuples[3].D + "");
            form.Length2Down.Value = decimal.Parse(line.hTuples[4].D + "");
        }
        /// <summary>
        /// 清除这个线对象
        /// </summary>
        public void ClearObject()
        {
            if (lines != null && lines.Count > 0)
            {
                foreach (HDrawingObjectEx line in lines)
                {
                    var ho = line.HDrawingObject;
                    if (ho.ID == 0) { continue; }
                    hw.HalconWindow.DetachDrawingObjectFromWindow(ho);
                    ho.Dispose();
                }
            }
            if (line == null) return;
            var hobject = line.HDrawingObject;
            if (hobject.ID == 0) { return; }
            hw.HalconWindow.DetachDrawingObjectFromWindow(hobject);
            hobject.Dispose();
        }
        /// <summary>
        /// 放置区域
        /// </summary>
        public void Put_Recangle2() {
            if (HideIntputImage == null) {
                throw new Exception("当前图像为空! \r\n");
            }
            if (line==null)
            {
                throw new Exception("请先画矩形设置区域! \r\n");
            }
            ClearObject();
            HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(form.RowDown.Value + ""), double.Parse(form.ColumnDown.Value + ""), double.Parse(form.PhiDown.Value + ""),
                double.Parse(form.Length1Down.Value + ""), double.Parse(form.Length2Down.Value + ""));
            HOperatorSet.DispObj(rectangle,hw.HalconWindow);
            putCheck = true;
            //保存一下第一次基准的数据
            //写入校验数据
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            string path1 = path + $"\\{form.Text}.txt";
            using (FileStream sw = new FileStream(path1, FileMode.Create, FileAccess.Write))
            {
                sw.Write(Encoding.UTF8.GetBytes(putCheck.ToString() + $",{HideIntputArrayRows[0]},{HideIntputArrayColumns[0]},{HideIntputArrayPhis[0]}"), 0, Encoding.UTF8.GetBytes(putCheck.ToString() + $",{HideIntputArrayRows[0]},{HideIntputArrayColumns[0]},{HideIntputArrayPhis[0]}").Length);
            }
        }

        public void Tool_Run() {
            HOperatorSet.ClearWindow(hw.HalconWindow);
            HOperatorSet.DispObj(HideIntputImage,hw.HalconWindow);
            Run(1);
        }

        public void Run(int RunCount) {
            if (HideIntputImage == null)
            {
                throw new Exception("当前图像为空! \r\n");
            }
            ClearObject();
            if (form.comboBox1.SelectedIndex == 1) return;
            string[] strdb = new string[20];
            // 读取校验数据
            string path1 = path+$"\\{form.Text}.txt";
            bool putCheck = false;
            byte[] data = new byte[1024 * 1024 * 2];
            try 
            {
                using (FileStream sw = new FileStream(path1, FileMode.Open, FileAccess.Read))
                {
                    int index = sw.Read(data, 0, data.Length);
                    strdb = Encoding.UTF8.GetString(data, 0, index).Split(',');
                    putCheck = bool.Parse(strdb[0].ToLower());
                }
            }
            catch { }

            if (putCheck)
            {
                HOperatorSet.SetColor(hw.HalconWindow, "red");
                HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(form.RowDown.Value + ""), double.Parse(form.ColumnDown.Value + ""), double.Parse(form.PhiDown.Value + ""),
                double.Parse(form.Length1Down.Value + ""), double.Parse(form.Length2Down.Value + ""));
                hObjects.Clear();
                for (int i = 0; i < HideIntputArrayRows.Length; i++)
                {
                    HObject ho_RegionAffineTrans = UtiyHalcon.MatrixCalculate(rectangle, HideIntputArrayRows[i], HideIntputArrayColumns[i], HideIntputArrayPhis[i], double.Parse(strdb[1]), double.Parse(strdb[2]), double.Parse(strdb[3]));
                    HOperatorSet.ReduceDomain(HideIntputImage, ho_RegionAffineTrans, out HObject image);
                    hObjects.Add(image);
                }
                HOperatorSet.SetDraw(hw.HalconWindow, "fill");
                List<HObject> ResultHobject = new List<HObject>();
                double areaSum = 0;
                foreach (HObject hObject in hObjects)
                {
                    HObject region = hObject;
                    //缩放对比度
                    if (form.ScaleComboBox.SelectedIndex == 0)
                    {
                        HOperatorSet.ScaleImage(region, out region, double.Parse(form.scaleMax.Value + ""), double.Parse(form.scaleMin.Value + ""));
                    }
                    //二值化处理
                    if (form.throldComboBox.SelectedIndex == 0)
                    {
                        HOperatorSet.Threshold(region, out region, double.Parse(form.throldMin.Value + ""), double.Parse(form.throldMax.Value + ""));
                    }
                    if (form.selectComboBox.SelectedIndex == 0)
                    {
                        HOperatorSet.SelectShape(region, out region, "area", "and", double.Parse(form.MinArea.Value + ""), double.Parse(form.MaxArea.Value + ""));
                    }
                    ResultHobject.Add(region);
                    HOperatorSet.AreaCenter(region, out HTuple area, out HTuple row, out HTuple column);
                    if (area.Length == 0) continue;
                    areaSum += area;
                }
                form.numericUpDown3.Value = decimal.Parse((areaSum / hObjects.Count) + "");
                if (RunCount == 1)
                {
                    foreach (HObject hObject in ResultHobject)
                    {
                        HOperatorSet.DispObj(hObject, hw.HalconWindow);
                    }
                }
                HOperatorSet.SetDraw(hw.HalconWindow, "margin");

                //判断瑕疵 面积接受公差
                foreach (HObject hObject in ResultHobject)
                {
                    HOperatorSet.AreaCenter(hObject, out HTuple area, out HTuple row, out HTuple column);
                    //设置文本显示的坐标
                    HOperatorSet.SetTposition(hw.HalconWindow, row, column);
                    //设置字体
                    HOperatorSet.SetFont(hw.HalconWindow, "宋体" + "-Normal-" + 25);
                    double area1 = double.Parse(form.acceptArea.Value + "") - double.Parse(form.toleranceBlod.Value + "");
                    double area2 = double.Parse(form.acceptArea.Value + "") + double.Parse(form.toleranceBlod.Value + "");
                    if (area1 <= area && area2 >= area)
                    {
                        //设置颜色
                        HOperatorSet.SetColor(hw.HalconWindow, "green");
                        //设置文字
                        HOperatorSet.WriteString(hw.HalconWindow, "瑕疵OK");
                    }
                    else
                    {
                        //设置颜色
                        HOperatorSet.SetColor(hw.HalconWindow, "red");
                        //设置文字
                        HOperatorSet.WriteString(hw.HalconWindow, "瑕疵NG");
                    }
                }
            }
            else {
                throw new Exception("瑕疵工具: 区域未画制!");
            }
        }

        public void Updata_Bold() {
            //ClearObject();

            //string[] strdb = new string[20];
            //// 读取校验数据
            //string path1 = path + $"\\{form.Text}.txt";
            //bool putCheck = false;
            //byte[] data = new byte[1024 * 1024 * 2];
            //try
            //{
            //    using (FileStream sw = new FileStream(path1, FileMode.Open, FileAccess.Read))
            //    {
            //        int index = sw.Read(data, 0, data.Length);
            //        strdb = Encoding.UTF8.GetString(data, 0, index).Split(',');
            //        putCheck = bool.Parse(strdb[0].ToLower());
            //    }
            //}
            //catch { }
            //HOperatorSet.ClearWindow(hw.HalconWindow);
            //HOperatorSet.DispObj(HideIntputImage, hw.HalconWindow);
            //HOperatorSet.SetColor(hw.HalconWindow, "red");
            //HOperatorSet.GenRectangle2(out HObject rectangle, double.Parse(form.RowDown.Value + ""), double.Parse(form.ColumnDown.Value + ""), double.Parse(form.PhiDown.Value + ""),
            //double.Parse(form.Length1Down.Value + ""), double.Parse(form.Length2Down.Value + ""));
            //for (int i = 0; i < HideIntputArrayRows.Length; i++)
            //{
            //    HObject ho_RegionAffineTrans = UtiyHalcon.MatrixCalculate(rectangle, HideIntputArrayRows[i], HideIntputArrayColumns[i], HideIntputArrayPhis[i], double.Parse(strdb[1]), double.Parse(strdb[2]), double.Parse(strdb[3]));
            //    HOperatorSet.ReduceDomain(HideIntputImage, ho_RegionAffineTrans, out HObject image);
            //    hObjects.Add(image);
            //}
            //HOperatorSet.SetDraw(hw.HalconWindow, "fill");
            //List<HObject> ResultHobject = new List<HObject>();
            //double areaSum = 0;
            //foreach (HObject hObject in hObjects)
            //{
            //    HObject region = hObject;
            //    //缩放对比度
            //    if (form.ScaleComboBox.SelectedIndex == 0)
            //    {
            //        HOperatorSet.ScaleImage(region, out region, double.Parse(form.scaleMax.Value + ""), double.Parse(form.scaleMin.Value + ""));
            //    }
            //    //二值化处理
            //    if (form.throldComboBox.SelectedIndex == 0)
            //    {
            //        HOperatorSet.Threshold(region, out region, double.Parse(form.throldMin.Value + ""), double.Parse(form.throldMax.Value + ""));
            //    }
            //    if (form.selectComboBox.SelectedIndex == 0)
            //    {
            //        HOperatorSet.SelectShape(region, out region, "area", "and", double.Parse(form.MinArea.Value + ""), double.Parse(form.MaxArea.Value + ""));
            //    }
            //    ResultHobject.Add(region);
            //    HOperatorSet.AreaCenter(region, out HTuple area, out HTuple row, out HTuple column);
            //    if (area.Length == 0) continue;
            //    areaSum += area;
            //}
            //form.numericUpDown3.Value = decimal.Parse((areaSum / hObjects.Count) + "");
            //foreach (HObject hObject in ResultHobject)
            //{
            //    HOperatorSet.DispObj(hObject, hw.HalconWindow);
            //}
            //HOperatorSet.SetDraw(hw.HalconWindow, "margin");
        }
    }
}
